package org.NooLab.somclients.domains.som;

import java.util.ArrayList;


import org.NooLab.utilities.files.DFutils;
import org.NooLab.utilities.logging.LogControl;
import org.NooLab.utilities.logging.PrintLog;
import org.NooLab.utilities.strings.StringsUtil;

 
import org.NooLab.field.FieldIntf;
import org.NooLab.itexx.storage.DataStreamProviderIntf;
import org.NooLab.itexx.storage.TexxDataBaseSettingsIntf;
import org.NooLab.itexx.storage.somfluid.db.DataBaseAccessDefinition;
import org.NooLab.somclients.app.up.IniProperties;
import org.NooLab.somclients.components.params.SomClientParamPkgIntf;
import org.NooLab.somclients.domains.ScSomfixParamPkgIntf;
import org.NooLab.somclients.intf.SomClientsPublicIntf;
import org.NooLab.somfluid.SomFluidFactory;
import org.NooLab.somfluid.SomFluidProperties;
import org.NooLab.somfluid.SomFluidPropertiesHandler;
import org.NooLab.somfluid.SomFluidPropertiesHandlerIntf;
import org.NooLab.somfluid.properties.PersistenceSettings;
import org.NooLab.somfluid.properties.SomDynamicsIntf;
import org.NooLab.somfluid.storage.ContainerStorageDevice;
import org.NooLab.somfluid.storage.FileOrganizer;
import org.NooLab.somfluid.structures.VariableSettingsHandlerIntf;

import org.NooLab.somfluid.tasks.SomFluidMonoTaskIntf;
import org.NooLab.somfluid.tasks.SomFluidProbTaskIntf;
import org.NooLab.somfluid.tasks.SomFluidTaskIntf;
import org.NooLab.structures.ITexxPublicIntf;
import org.NooLab.structures.InstanceProcessControlIntf;
import org.NooLab.structures.SomTaskDependProcessIntf;





/**
 * 
 * 
 * 
 * 
 * 
 *
 */
public class SomProducer{

	ScSomfixParamPkgIntf scSomParams;
	AstorInstance astorInstance;
	
	
	PrintLog out = new PrintLog(2,false);


	public boolean somInstanceStopped;
	
	// ========================================================================
	public SomProducer(SomClientParamPkgIntf pp) {
		// 
		scSomParams = (ScSomfixParamPkgIntf)pp;
		
		
	}
	// ========================================================================
	
	
	
	public void produce() {
		// 
		
		int somType = scSomParams.getSomType() ;
		
		if (somType == FieldIntf._INSTANCE_TYPE_ASTOR ){
			produceAstorSom() ;
		}
		if (somType == FieldIntf._INSTANCE_TYPE_OPTIMIZER ){
			producePurpleSom() ;
		}
	}
	

	private Arguments readTemplateConfiguration(String string){

		String str, cfg, rsrcpath ;
		Arguments arguments = new Arguments();
		
		rsrcpath = "org/NooLab/somclients/domains/som/resources";
		cfg = "somclients-som-config-xml" ;
		 
		/*
              	-prj:base
				-homedir:"D:/data/iTexx/app/Astor" 
				-cfg:astor-config.xml
				-sourcemode:catalog
				-size:298
				-resume:1
				-onCompletion:exit
				-startSomClients:1,7211,7210
				-context:itexx
				-loglevel:2
		 */
		arguments.homeDir = "app/Astor";
		// sfProperties.
		
		//  
		str = IniProperties.fluidSomProjectBasePath; // before, we passed readbinpref() !
		arguments.homeDir = DFutils.createPath( str, arguments.homeDir) ;

		arguments.nodeCount = 29; // 299  500 5000
		arguments.onCompletion = "";
		arguments.configFile = "astor-config.xml";
		arguments.contextMode = "itexx";
		
		arguments.logLevel = 2;
		
		return arguments;
	}

	// ----------------------------------------------------
	
	private void produceAstorSom(){
		Arguments arguments;
		SomClientsPublicIntf somClientsHost=null;
		
		arguments = readTemplateConfiguration("astor");
		
		
		if (arguments!=null){
			
			astorInstance = new AstorInstance( this );
			
			astorInstance.contextMode = "itexx"; // arguments.contextMode ;
		
			astorInstance.homedir = arguments.homeDir ;          // D:/data/iTexx/app/Astor
			astorInstance.projectname = arguments.projectName ;  // base
			astorInstance.logLevel = arguments.logLevel ;
			
			astorInstance.nodeCount = arguments.nodeCount ;
			astorInstance.glueMode = SomFluidFactory._GLUE_MODULE_ENV_NONE ;
			
			astorInstance.resumeMode = true;
			astorInstance.onCompletion = arguments.onCompletion; 
			
			astorInstance.setNodeCount(arguments.nodeCount) ;
			
			out.print(1, "starting Astor-Som instance..."); // TODO: don't forget the GUID !!!
			
			somClientsHost = scSomParams.getHost();
			scSomParams.useDirectReference();
			

			
			astorInstance.setTransferSourceDataBase( SomFluidTaskIntf._SOURCE_DB_SOMNODES ,
										  	 		 scSomParams.getSourceDbName(),
										  	 		 scSomParams.getSomId());

			astorInstance.setTransferTargetDataBase( SomFluidTaskIntf._TARGET_DB_HISTODOC ,
				  	 						 	 	 scSomParams.getTargetDbName(),
				  	 						 	 	 scSomParams.getSomId());

			
			astorInstance.startInstance( somClientsHost, scSomParams.useDirectReference()) ;
			
		}

		
	}
	
	
	// ----------------------------------------------------
	private void producePurpleSom() {
	
		
	}

	
	
}
/*
-prj:base
-homedir:"D:/data/iTexx/app/Texx" 
-sourcemode: catalog|[ file|folder="[fpath]" ]|[list="filename"]    if file,folder then " are mandatory
-cfg:astor-config.xml
-size:298
-resume:1
-onCompletion:exit
-startSomClients:1,7211,7210   this triggers the start of the 2nd layer in SomClients via TCP
                               using the respective ports for communication;
                               note that the instance itself is already running through iTexx; 
                               Astor just triggers the start of the first=base instance 
-context:itexx   
-loglevel:2


 */
class Arguments{
	
	boolean appletRequested=false;
	boolean defaultsRequested=false;
	
	String configFile  = "astor-config.xml";
	String homeDir     = "" ;
	String projectName = "itx" ; 
	String jarDir      = "";
	String contextMode = InstanceProcessControlIntf._APP_CONTEXT_ALONE ; // itexx or standalone, running user based projects
	String sourceFileDedicated="",sourceFilesByFolder="",sourceFileByListingFile="";
	int logLevel= 2;
	
	DFutils fileutil = new DFutils();
	StringsUtil strgutil = new StringsUtil();
	int resumeMode;
	int nodeCount;
	String onCompletion = InstanceProcessControlIntf._APP_COMPLETION_SERVICE ;
	
	// ------------------------------------------------------------------------
	
}

class AstorInstance implements Runnable{

	
	
	SomFluidFactory sfFactory;
	SomFluidProperties sfProperties;
	SomFluidPropertiesHandlerIntf sfPropertiesDefaults;
	
	SomFluidProbTaskIntf sfTask;
	
	InstanceProcessControlIntf somProcessControl ;

	
	public boolean resumeMode;
	public int glueMode;
	public int logLevel;
	public String projectname;
	public String homedir;
	public String contextMode;
	public String onCompletion;
	
	
	Thread smiThrd;
	SomProducer app;
	
	boolean somIsSecondary = true ;
	int instanceType;
	int nodeCount = 400;
	
	PrintLog out ;
	private long somId;
	
	private int sourceDbType=0;
	private String sourceDbName="";  // for SOM learning
	
	private int targetDbType = -1;
	private String transferSourceDbName; // for reading nodes etc...
	private String transferTargetDbName; // the new input db for SOM...
	
	// ========================================================================
	public AstorInstance(SomProducer app){
		
		this.app = app;
		smiThrd = new Thread(this, "scSomModuleInstance");
		out = app.out ;
	}
	
	public void startInstance() {
		
		instanceType = FieldIntf._INSTANCE_TYPE_ASTOR ;
		smiThrd.start();
	}

	public void startInstance( SomClientsPublicIntf somClientsHost, 
							   boolean useDirectReference) {

		somIsSecondary = true;
		startInstance();
	}

	// ------------------------------------------------------------------------
	
	public void close() {
		
		//  
		if (somProcessControl!=null){
			somProcessControl.interrupt(0);
		}else{
			System.err.println("Nothing to stop, <somProcessControl> was not up and running...");
		}

		app.somInstanceStopped = true ;
	}
	
	public void resume() {
		// 
		
		
		resumeMode = checkForPossibleResuming();
		smiThrd.start();
	}
	
	// ========================================================================
	
	
	
	
	public void setSourceDataBase(int sourceDbtype, String sourceDbname) {
		// 
		setTransferSourceDataBase( sourceDbtype, sourceDbname,0);
	}

	public void setTransferSourceDataBase( int sourceDbtype, String sourceDbname, long somId) {
		// 
		sourceDbType = sourceDbtype;
		transferSourceDbName = sourceDbname;		
		this.somId = somId;
	}

	public void setTransferTargetDataBase(int dbtype, String targetDbname, long somid) {
		 
		targetDbType = dbtype ;
		transferTargetDbName = targetDbname ;
	}

	public void setNodeCount(int nodecount) {
		
		if (nodecount>25){
			nodeCount = nodecount;
		}
	}

	private boolean checkForPossibleResuming() {
		
		return false;
	}
	
	public boolean checkForConfiguration() {
		// 
		return true;
	}
	
	@Override
	public void run() {

		if (resumeMode){
			
			try {
			
				resumeSOM();

			} catch (Exception e) {
				e.printStackTrace();
			}
			
		}else{
			prepareAstorSom();
		}
		

		
	}
	// ----------------------------------------------------


	private void prepareAstorSom() {

			
		
		// this might be called with some URL or xml-string that represents the source containing the settings
		// if this exists, it will be loaded
		
		sfProperties = SomFluidProperties.getInstance( "" ); // not available
		
		String somSourceDb = app.scSomParams.getSourceDbName();
		
		if (app.scSomParams.getSomLevel()>=2){
			 
			defineDataBaseAccessData(somSourceDb, TexxDataBaseSettingsIntf._DATABASE_STRUC_RNDDOCS_L1);  
			
		}else{
			defineDataBaseAccessData(somSourceDb, TexxDataBaseSettingsIntf._DATABASE_STRUC_CONTEXTS_L0);
		}
		
		// alternatively... load from /resources in jar ...
		 
		
		sfProperties.setApplicationContext(contextMode);
		
		sfPropertiesDefaults = new SomFluidPropertiesHandler(sfProperties);
		
		explicitlySettingProperties();
		
		sfProperties.setOnCompletion( onCompletion );
		
		double[] params=null;
		sfProperties.setGrowthMode( app.scSomParams.getGrowthMode(), params);
		sfProperties.setGrowthSizeAdaptationIntensity( app.scSomParams.getGrowthIntensity() );
		
		int[] gm = app.scSomParams.getGrowthMode();
		boolean gb = (gm.length>0) && (gm[0] != SomDynamicsIntf._SOM_GROWTH_NONE); 
		
		if (gb){
			sfProperties.setActivationOfGrowing(true);
		}
		
		// defining the variables... in case of astordocs, we use all fields starting with "n_*" 
		VariableSettingsHandlerIntf variableSettings = sfProperties.getVariableSettings() ;
		ArrayList<String> excludeds = variableSettings.getAbsoluteExclusions();  //  larger than fieldLabels

		// changing && re-setting it...
		variableSettings.setInitialSelection(new String[]{"n_*","doc*"});
		variableSettings.setBlackListedVariables(new String[]{"*id","*time","status"});
		
		// 
		
		
		sfFactory = SomFluidFactory.get(sfProperties);					   // creating the factory; calling without "factorymode" parameter, optimizer will be assumed	
		 
		 
		sfFactory.saveStartupTrace( FieldIntf._INSTANCE_TYPE_SOM, 
									sfPropertiesDefaults.getStartupTraceInfo() );
		
		// where is this going to be saved? it should NOT overwrite anything
		// saving the properties needs a FileOrganizer, PersistenceSettings and a project name !
		// otherwise it will not find the appropriate folder, instead it will create a folder "somewhere"
		
		String rootdir = sfProperties.getSystemRootDir();
		String prjname = app.scSomParams.getProjectName() ;
		
		sfProperties.getPersistenceSettings().setProjectName( prjname ) ; 
		
		if (DFutils.folderExists(rootdir)){
			sfProperties.getPersistenceSettings().setPathToSomFluidSystemRootDir(rootdir) ;
		}
		sfProperties.getPersistenceSettings().setAppNameShortStr("astor") ;
		
		
		// 
		sfProperties.save();
		sfProperties.exportXml();  					// String xstr = sfProperties.getExportedXml();
		
		
		/*
		 * everything is started by "SomFluid" through a queued task mechanism;
		 * 
		 * different application types use different perspectives onto the task
		 * 
		 */
		  
		sfTask = (SomFluidProbTaskIntf)sfFactory.createTask( FieldIntf._INSTANCE_TYPE_ASTOR ); //
		
		sfTask.setStartMode(1) ;             		// default=1 == starting after producing the FluidSom
										 			//        <1 == only preparing, incl. 1 elementary run to load the data, 
		                                 			//              but not starting the modeling process (v switches in the middle between 3..100)
										 			//        >100  minimum delay in millis
		
		
		sfTask = (SomFluidProbTaskIntf)sfFactory.createTask( ); 
		sfTask.setStartMode(1) ;  
		 
		 
		sfTask.activateDataStreamReceptor(true) ;   // after learning the initial bunch of data
													// Astor Som switches to "online learning"
		
		// these have been provided as :  -startSomClients:1,7211,7210
		
		// first we request an object
		SomTaskDependProcessIntf dependencies = sfFactory.getTaskDependenciesObject(); 
	
		dependencies.setDependencyType( ITexxPublicIntf._ITX_DEPENDENT_PROCESS_SOMCLIENTS) ;
		dependencies.setCommPorts(7211,7210);
		
		sfTask.setDependencies(dependencies);

		// if we would not set this, it would take the itexx default DB (randomwords) as source
		// e.g. sourceDbType = SomClientParamPkgIntf._SOURCE_DB_SOMNODES ,
		
		int prepareAbstraction = app.scSomParams.getAbstractionSupport() ;
		sfTask.setPreparingAbstraction(prepareAbstraction) ;
		
		sourceDbType = TexxDataBaseSettingsIntf._DATABASE_STRUC_RNDDOCS_L1;
		// this source relates to the SOM learning task, it is astordocs or randomwords
		sourceDbName = app.scSomParams.getTransferTargetDbName(); 
		sfTask.setSourceDatabase(sourceDbType,sourceDbName) ;
		 
		transferSourceDbName =  app.scSomParams.getTransferSourceDbName() ;
		transferTargetDbName =  app.scSomParams.getTransferTargetDbName() ;
		
		sfTask.setTransferSourceDatabase( sourceDbType, transferSourceDbName ,somId) ;
		sfTask.setTransferTargetDatabase( targetDbType, transferTargetDbName ) ;
		
		
		try {
			
			sfFactory.produce( sfTask );
							// this produces the SomFluid and the requested som-type according to
							// SomFluidProperties._SOMTYPE_MONO, referring implicitly to sfTask; 
							
		} catch (Exception e) {
			e.printStackTrace();
		}          		
		
	 	// if we like to have graphical output, then start the applet for displaying it and 
		// define shake hands by means of GlueClients...
		

	}


	
	
	private void defineDataBaseAccessData(String dbname, int structureCode) {

		DataBaseAccessDefinition dbAccess ;
		TexxDataBaseSettingsIntf dbSettings ;
		ArrayList<String> fieldlist ;
		
		try {
			
			 
			// reading from  dbDefinitionResource ="texx-db-definition-xml" ; in project iTexxStorage...
			sfProperties.getDatabaseDefinitionInfo(dbname,structureCode); // e.g. "randomwords"
			
			dbAccess = sfProperties.getDbAccessDefinition() ;
			 
			dbSettings = sfProperties.getDatabaseSettings() ;
			
			fieldlist = dbSettings.getTableFields() ;
			
		} catch (Exception e) {
			
			e.printStackTrace();
		}
		
	}
	
	private void explicitlySettingProperties(){
		
		 
		PersistenceSettings ps;
		 

		String str, dbDefinitionResource="" ;
		
		try {
			
			
			String instance = "astor";
			
			if (instance.contentEquals("astor")){

				sfPropertiesDefaults.setInstance( "astor" ,nodeCount );
				//check this !!
				instanceType = sfProperties.getSomInstanceType() ;
									
				sfProperties.setSomType( FieldIntf._SOMTYPE_PROB ) ; // == associative storage = Astor
				
				// choose a fixed or a fluid grid
				sfPropertiesDefaults.setGridType( FieldIntf._SOM_GRIDTYPE_FIXED ) ;
			    //sfPropertiesDefaults.setGridType( FieldIntf._SOM_GRIDTYPE_FLUID) ;
				
				
				// choose a guessing instance: low-resolution grid, speeding the 
				// node selection in large grids
				
				
				
				// this applies only if the instance is of type "som", which includes optimizing of the model
				// the absolute number of different models that will be checked
				sfPropertiesDefaults.setOptimizerStoppingCriteria( -1 ) ;					
									//	optionally, any of the following parameters ( [n], 21, 100, 0.8)


				/* we may create a complete som for classification from externally defined "top-down" profiles
				   that's very important in design approaches
				   note that the data file will be interpreted as a collection of prototypes;
				   yet, if the data contain more records than it has been defined as the number of prototypes,
				   it will be regarded as empirical data  	
				   by default = Off */
				sfPropertiesDefaults.setDataSimulationByPrototypes( 0 );				// or any number >100 for switching on
				sfPropertiesDefaults.setMaxNumberOfPrototypes(50) ;
				
				/*
				 * the "outcome" or target can be mapped onto a binary variable
				 * level of definition parameters may be "raw" or "relative" (=normalized, hence expressing percentage quantiles)
				 * 
				 * will be overridden by settings from the optional description file about variable settings
				 */
				// sfPropertiesDefaults.setSingleTargetDefinition( "raw", 0.1, 0.41, "intermediate" ) ;
									// the Single-Target-Mode can be defined with several non-contiguous intervals within [0..1] 
				
									// we have to check rather soon whether such values occur at all 
									// in the TV column of the table: on data import, or reloading of the SomData 
				
				sfPropertiesDefaults.activateGrowingOfSom( false, 300, 15.1) ; // n = max node size, averaged across the top 15% of nodes acc. to size

			}

			// variables...
			defineInitialVariableSettings(); 
									// alternatively, defineInitialVariableSettings([filename]);
									// (re-)creating the file
									// sfPropertiesDefaults.exportVariableSettings(null, ""); // a dedicated path could be applied
			 
			
			// -------------------------------------------------------------------------------
			
			// "file", "db", "tcp"
			sfPropertiesDefaults.setDataSourcing( DataStreamProviderIntf._DSP_SOURCED_FILE ,0) ; 						
			sfPropertiesDefaults.setDataSourceName( IniProperties.dataSource );
			// org.NooLab.astor.app.up.
			
			// ... overruling by setting a database as source 
			sfPropertiesDefaults.setDataSourcing( DataStreamProviderIntf._DSP_SOURCED_DB ,0) ;
			// dbDefinitionResource = "texx-db-definition-xml" ; // default
			sfPropertiesDefaults.setDatabaseDefinitionResource( dbDefinitionResource,"randomwords",1 );
			 
			 
			// -------------------------------------------------------------------------------
			// optional, if there are indeed plugin files ...
			// dependent on appcontext
			if (sfProperties.isITexxContext()){
				
out.print(4, "context detected : itexx");				
				str = sfProperties.getSystemRootDir();
out.print(4, "system root (1): "+str);				
				if (str.length()==0){
					
					sfProperties.setSystemRootDir( IniProperties.fluidSomProjectBasePath) ;
					str = sfProperties.getSystemRootDir();    // D:/data/iTexx/  ... it is empty when started by iTexx
out.print(4, "system root (2): "+str);				
					if (str.length()==0){
						str = DFutils.getParentDir(homedir, 2);
						sfProperties.setSystemRootDir( str) ; // D:/data/iTexx/app/Astor
						str = sfProperties.getSystemRootDir();
out.print(4, "system root (3): "+str);				
					}
out.print(4, "system root (4): "+str);						
				}
				 
				
				str = DFutils.createPath( sfProperties.getSystemRootDir(), "app/Astor/plugins/") ;
out.print(4, "system root + partial algo path : "+str);				
				sfPropertiesDefaults.setAlgorithmsConfigPath( str );
			}else{
				sfPropertiesDefaults.setAlgorithmsConfigPath( "D:/dev/java/somfluid/plugins/" );
			}
			

			 
			
			sfProperties.addFilter( "var",0.3,"<",1,1,true);       
									// filter that act on the values of observations
			   						// can be defined only with an existing factory since we need access to the data
			   						// !! not yet functional

			
			sfPropertiesDefaults.initializeDefaults();
			
			
			str = sfProperties.getSystemRootDir() ;
			str = IniProperties.fluidSomProjectBasePath;
			sfProperties.setSystemRootDir(str) ;
			
			
			sfProperties.setExtendingDataSourceEnabled(true); 
			
			
			// controlling the granularity/verbosity of console messages 
			if (LogControl.Level>2){
				sfProperties.setShowSomProgress( SomFluidProperties._SOMDISPLAY_PROGRESS_STEPS ) ; // default: _SOMDISPLAY_PROGRESS_BASIC
			}
			sfProperties.setShowSomProgress( SomFluidProperties._SOMDISPLAY_PROGRESS_STEPS );
			
			sfProperties.setMultiProcessingLevel(0); 
			
		} catch (Exception e) {
			e.printStackTrace();
			System.err.println("The system will exit.");
			System.exit(-7) ;
		}
		
		// --- --- ---

		/*
		 * in this folder there will be enumerated sub-folders containing the results
		 */
		String resultFolder = sfPropertiesDefaults.setResultsPersistence(1,"app/Astor");	// optionally: a dedicated path
		       resultFolder = sfPropertiesDefaults.getResultBaseFolder();

		// set ready flag
		sfProperties.setInitializationOK(true) ;						
	}
	
	  
	 
	 
	/**
	 * a small compartment, which optionally also may read the initial variable settings from a file
	 * 
	 * @param filename
	 * @throws Exception 
	 */
	private void defineInitialVariableSettings( String ...filenames) throws Exception {

		boolean configByFileExcluded=false;
		String[] filnames = new String[0];
		
		

		if ((filenames!=null) && (filenames.length>0)){
			filnames = new String[ filenames.length];
			System.arraycopy(filenames, 0, filnames, 0, filnames.length) ;
		}
		
		if ((configByFileExcluded==false) && ((filenames==null) || (filenames.length==0) || (DFutils.fileExists(filenames[0])==false))){
			// String str  =IniProperties.lastProjectName; // = Astor
			
			String filepath = DFutils.createPath( IniProperties.fluidSomProjectBasePath, IniProperties.lastProjectName);
			
			filepath = DFutils.createPath( filepath , "data/description/");
			filepath = DFutils.createPath( filepath , "astor-variables.txt");
			
			String filename = sfPropertiesDefaults.checkForVariableDescriptionFile(0, filepath) ; 
			// 0 = typology file, 1 = textual description (background information)
			
			if (DFutils.fileExists(filename)){
				filnames = new String[]{filename};
			}
		}
		
		if ((filnames!=null) && (filnames.length>0) && (DFutils.fileExists(filnames[0]))){
			 
			if (sfPropertiesDefaults.loadVariableSettingsFromFile( filnames[0]) ){
				// recognizes format by itself, if successful, we may return
				return;
			}
		}
		
		// .................. do the following only if there was not a definition file
		
		
		// note that the data are not loaded at that point,
		// such it is only a request for blacklisting variables
		// if any those variables do not exist, no error message will appear by default
		
		// we provide a small interface for dealing with initial variable settings all at once
		VariableSettingsHandlerIntf variableSettings = sfPropertiesDefaults.getVariableSettingsHandler();

		variableSettings.setTargetVariables(""); 	
		variableSettings.setTvGroupLabels("") ;

		sfProperties.addFieldExclusionByIndex(15);
		sfProperties.setFieldExclusionByIndexFrom(15);
		sfProperties.setFieldExclusionByIndexUntil(15);
		sfProperties.setFieldExclusionByIndexFrom("wordlabel", 1); 
		sfProperties.setFieldExclusionByIndexUntil("wordlabel"); 
		sfProperties.setFieldExclusionByBetween(2,15);

	}

	

	private void resumeSOM() throws Exception{
		
		// loads an existing targeted SOM and starts/continues/repeats the optimizing according to the settings 
		// results are saved or provided to the Glue, then the Som-layer stops / application exits
	

		
		String startupTraceInfo="", lastproject="", systemroot="", propertiesFileName, dir;
		String[] infoStrings, infopart;
		FileOrganizer fileorg ;
		
		try {
											System.out.println("resuming...");
			instanceType = FieldIntf._INSTANCE_TYPE_SOM;
			
			startupTraceInfo = SomFluidFactory.loadStartupTrace( instanceType ) ;
		
			infoStrings = startupTraceInfo.split("\n");
			
			for (int i=0;i<infoStrings.length;i++){
				infopart = infoStrings[i].split("::");
				if (infopart[0].contains("cfgroot")) {
					systemroot = infopart[1];
				}
				if (infopart[0].contains("project")) {
					lastproject = infopart[1];
				}
			}
			
			if ((systemroot.length()==0) || (lastproject.length()==0) || (DFutils.fileExists(systemroot )==false)){
				out.printErr( 1, "Cannot resume, since boot/trace file was not found or it did not contain the relevant information.\n"+
							     "Astor will start normally, next time it will start in resume mode.\n") ;
				prepareAstorSom();
				return;
			}
			
			// load properties, still only as a bootstrap...
			sfProperties = SomFluidProperties.getInstance();
			sfProperties.setInstanceType( instanceType ) ;
			 
			fileorg = sfProperties.getFileOrganizer() ;
			
			sfProperties.setSystemRootDir(systemroot) ;
			sfProperties.getPersistenceSettings().setPathToSomFluidSystemRootDir(systemroot) ;
			sfProperties.getPersistenceSettings().setProjectName(lastproject) ;
			
			fileorg.setPropertiesBase(sfProperties);
			
			dir = fileorg.getObjectStoreDir("app/Astor");
			propertiesFileName = DFutils.createPath( dir, SomFluidProperties._STORAGE_OBJ ) ;
			
			// now loading the desired properties into a new object;
			ContainerStorageDevice storageDevice ;
			storageDevice = new ContainerStorageDevice();
			
			sfProperties = (SomFluidProperties)storageDevice.loadStoredObject(propertiesFileName) ;
			
			sfProperties.setFileOrganizer(fileorg) ;
			
			sfFactory = SomFluidFactory.get(sfProperties);	
			somProcessControl = sfFactory.getSomProcessControl() ; // sending messages into the SomProcess, like interrupt, injecting new best metric, changing properties and threshold on the fly ...
											sfFactory.getOut().print(2, "loading description of previous task ...");
			// loading the task and starting it (file = SomFluidTask.trace)
			Object taskObj = sfFactory.loadTaskTrace(lastproject);
			
			if (taskObj!=null){
				
				if (taskObj instanceof SomFluidProbTaskIntf) {
					SomFluidProbTaskIntf sfTask = (SomFluidProbTaskIntf)taskObj ;
					sfTask.setResumeMode(1);
					sfFactory.produce( sfTask );
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
	
}



